#include "myStdio.h"

FILE_* fopen_(const char* pathname, const char* mode)
{
    int flags = 0;
    int defaultMode = 0666; // 默认创建权限
    
    if(strcmp(mode, "r") == 0)
    {
        flags |= O_RDONLY;
    }
    else if(strcmp(mode, "w") == 0)
    {
        flags |= (O_WRONLY | O_CREAT | O_TRUNC);
    }
    else if(strcmp(mode, "a") == 0)
    {
        flags |= (O_WRONLY | O_CREAT | O_APPEND);
    }
    else
    {
        // TODO:r+, w+...
    }

    int fd = 0;
    if(flags & O_RDONLY)  fd = open(pathname, flags);
    else  fd = open(pathname, flags, defaultMode);

    if(fd < 0)
    {
        const char* err = strerror(errno);
        write(2, err, strlen(err));
        return NULL;    // 打开文件失败返回NULL的原因
    }

    FILE_* fp = (FILE_*)malloc(sizeof(FILE_));
    assert(fp != NULL);

    fp->flags = SYNC_LINE; // 默认设置成行刷新
    fp->fileno = fd;
    fp->size = 0;
    fp->capacity = SIZE;
    memset(fp->buffer, 0, SIZE);

    return fp;  // 打开文件成功返回FILE*的原因
}

void fwrite_(const void* ptr, int num, FILE_* fp)
{
    // 数据写入到缓冲区
    memcpy(fp->buffer + fp->size, ptr, num); // 这里不考虑缓冲区溢出的问题
    fp->size += num;

    // 是否刷新缓冲区
    if(fp->flags & SYNC_NOW)
    {
        write(fp->fileno, fp->buffer, fp->size);
        fp->size = 0; // 清空缓冲区
    }
    else if(fp->flags & SYNC_LINE)
    {
        // 不考虑abcd\nef的情况
        if(fp->buffer[fp->size - 1] == '\n')
        {
            write(fp->fileno, fp->buffer, fp->size);
            fp->size = 0; // 清空缓冲区
        }
    }
    else if(fp->flags & SYNC_FULL)
    {
        if(fp->size == fp->capacity)
        {
            write(fp->fileno, fp->buffer, fp->size);
            fp->size = 0; // 清空缓冲区
        }
    }
    else
    {
        return;
    }
}

void fflush_(FILE_* fp)
{
    if(fp->size > 0)  write(fp->fileno, fp->buffer, fp->size);
	fsync(fp->fileno);
	fp->size = 0;
}

void fclose_(FILE_* fp)
{
    fflush_(fp);
    close(fp->fileno);
    free(fp);
}


